from django.db import models

from django.contrib.auth.models import AbstractUser, BaseUserManager
from django.core import validators
from django.utils.translation import ugettext_lazy as _

# Create your models here.

## para tabla personalizada de usuario e django

class MyUserManager(BaseUserManager):
    def create_user(self, email, username, password=None):
        """
        Creates and saves a User with the given email, date of
        birth and password.
        """
        # if not email:
            # raise ValueError('Users must have an email address')

        user = self.model(
            username=username,
            email=self.normalize_email(email),
            is_superuser=False, # True?
        )

        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_superuser(self, email, username, password, *kwargs):
        """
        Creates and saves a superuser with the given email, date of
        birth and password.
        """
        user = self.create_user(
            email,
            username,
            password=password,
        )
        user.is_admin = True
        user.save(using=self._db)
        return user

# tabla user personalzida
class Usuario(AbstractUser):
    objects = MyUserManager()
    
    username = models.CharField(
        _('username'),
        max_length=254,
        unique=True,
        help_text=_('Required. 254 characters or fewer. Letters, digits and @/./+/-/_ only.'),
        validators=[
            validators.RegexValidator(
                r'^[\w.@+-]+$',
                _('Enter a valid username. This value may contain only '
                  'letters, numbers ' 'and @/./+/-/_ characters.')
            ),
        ],
        error_messages={
            'unique': _("A user with that username already exists."),
        },
        db_index=True,
    )

    first_name = models.CharField(
        verbose_name= _('nombres'), 
        max_length=125, 
        blank=False
    )

    last_name = models.CharField(
        verbose_name= _('apellidos'),
        max_length=125,
        blank=False
    )

    is_admin = models.BooleanField(
        verbose_name = _("es admin"),
        default=False
    )

    ci = models.IntegerField(
        verbose_name=_("C.I."),
        default=0
    )
    
    ru = models.IntegerField(
        verbose_name=_("Registro universitario"),
        default=0,
    )

    tipo = models.IntegerField(
        verbose_name=_("Tipo"),
        default=1,
    )
    
    # requeridos por AbstractUser
    USERNAME_FIELD = 'username'
    REQUIERED_FIELDS = ['first_name', 'last_name']

    def __str__(self):
        return ("("+str(self.id) +") " + self.username)
    
    def get_full_name(self):
        return (self.first_name + " " + self.last_name)

    def change_password(self, new_password):
        self.set_password(new_password)
        self.save()

    def send_email(self, subject, message, from_email=None, **kwargs):
        """
        Sends an email to this User.
        """
        send_mail(subject, message, from_email, [self.email], **kwargs)

    def has_perm(self, perm, obj=None):
        "Does the user have a specific permission?"
        # Simplest possible answer: Yes, always
        return True

    # def save(self, *args, **kwargs):
        ''' asegurando que no haya otro usuario con los first_name , last_name'''
        # modificar lo siguiente
        # if not self.pk and self.has_usable_password() is False:
        #     self.set_password(self.password)

        # super(User, self).save(*args, **kwargs)

    @property
    def is_staff(self):
        "Is the user a member of staff?"
        # Simplest possible answer: All admins are staff
        return self.is_admin
    
    # class Meta:
    #     ordering = ('created',)
    
####

class Noticia(models.Model):

    tipo = models.IntegerField(
        verbose_name = _("Tipo"),
        default=1
    )

    para = models.IntegerField(
        verbose_name = _("Dirigido a quienes?"),
        default=1
    )
    
    titulo = models.CharField(
        verbose_name = _("Título"),
        max_length = 600,
        blank=False,
    )

    descripcion = models.CharField(
        verbose_name = _("Descripción"),
        max_length=9000,
        blank = False,
    )

    url = models.CharField(
        verbose_name = _("URL externa"),
        max_length=2000,
        default = "",
        blank = True,
    )

    # metodos
    def __str__(self):
        return ("("+ str(self.id) + ") "+ self.titulo)

class NotificacionNoticia(models.Model):

    usuario = models.ForeignKey(
        Usuario,
        verbose_name = _("Usuario a la que va dirigida"),
    )

    tipo = models.IntegerField(
        verbose_name=_("tipo"),
        default=1
    )

    visto = models.BooleanField(
        verbose_name = _("Visto?"),
        default = False
    )

    suscrito = models.BooleanField(
        verbose_name = _("El usuario se ha suscrito?"),
        default = False
    )

    titulo = models.CharField(
        verbose_name = _("Título de la notificación"),
        max_length=500,
    )

    descripcion = models.CharField(
        verbose_name = _("Descripción"),
        max_length=5000,
    )

    url = models.CharField(
        verbose_name = _("URL externa (opcional)"),
        max_length=2000,
        default="",
        blank = True
    )

    # metodos
    def __str__(self):
        return ("(" + str(self.id) + ") " + self.titulo + ", usuario:" +
                str(self.usuario))

    # class Meta:
    #     ordering = ('created',)

class Suscripcion(models.Model):
    
    noticia = models.ForeignKey(
        Noticia,
        verbose_name = _("Noticia en la que se basa (opcional)"),
        blank=True
    )

    nombre_actividad = models.CharField(
        verbose_name = _("Nombre de la actividad"),
        max_length = 500,
    )

    descripcion = models.CharField(
        verbose_name = _("Descripción de la actividad"),
        max_length = 5000,
    )

    cupo_maximo = models.IntegerField(
        verbose_name = _("Cupo máximo"),
    )

    para = models.IntegerField(
        verbose_name = _("Dirigido a"),
        default = 1,
    )

    # metodos
    def __str__(self):
        return ("(" + str(self.id) + ") " + self.nombre_actividad)

class NotificacionSuscripcion(models.Model):

    usuario = models.ForeignKey(
        Usuario,
        verbose_name = _("Usuario que se ha suscrito"),
    )

    suscripcion = models.ForeignKey(
        Suscripcion,
        verbose_name = _("Suscripcion a la que se ha suscrito"),
    )

    # metodos
    def __str__(self):
        return ("(" + str(self.id) + ") usuario:" + \
                str(self.usuario) + \
                str(self.suscripcion)
        )
    
    # class Meta:
    #     ordering = ('created',)


class PreMateria(models.Model):

    sigla = models.CharField(
        verbose_name=_("Sigla de la materia"),
        max_length = 200,
    )

    nombre = models.CharField(
        verbose_name = _("Nombre de la materia"),
        max_length = 300,
    )

    descripcion = models.CharField(
        verbose_name = _("Descripción detallada"),
        max_length = 1200,
    )

    cupos = models.IntegerField(
        verbose_name = _("Cupo máximo"),
    )

    nombre_docente = models.CharField(
        verbose_name = _("Nombre del docente (opcional)"),
        max_length = 200,
        default = "",
    )

    horario = models.CharField(
        verbose_name = _("Horario (opcional)"),
        max_length = 500,
        default = "",
    )

    aula = models.CharField(
        verbose_name = _("Aula (opcional)"),
        max_length = 200,
        default = "",
    )

    gestion = models.CharField(
        verbose_name = _("Gestión"),
        max_length = 100,
    )

    semestre = models.IntegerField(
        verbose_name = _("Semestre (1 al 10)"),
    )

    pre_requisitos = models.CharField(
        verbose_name = _("Pre requsitos (siglas materias)"),
        max_length = 200,
        default = ""
    )

    def __str__(self):
        return ("("+str(self.id)+") "+self.sigla + " - " + self.gestion)

    
class PreInscripcionEstudiante(models.Model):

    usuario = models.ForeignKey(
        Usuario,
        verbose_name = _("Estudiante pre inscrito"),
    )

    pre_materia = models.ForeignKey(
        PreMateria,
        verbose_name = _("Materia pre inscrita"),
    )

    def __str__(self):
        return ("("+str(self.id)+")" + "Estudiante:"+self.usuario + " Materia:"+self.pre_materia)

